#include "paral_py.h"

// 词法分析器，遍历整个文件，得到每一个语元的类型
int get_tok(struct paral_py_context *ctx)
{
	// 静态变量，仅被初始化一次，在获取tok后要预取
	static int LastChar = ' ';

	// Skip any whitespace.
	// 跳过所有空格、\v,\f,\r，\t只有在\n之后才有意义
	while (LastChar == ' ' || LastChar == '\v'  || LastChar == '\t')
	{
		LastChar = get_char(ctx);
	}

	if(LastChar == '\r'){
		printf("CR is not supported\n");
		exit(-1);
	}

	// 一开始行号是0，每遇到一个\n就代表到了新的行
	while (LastChar == '\n')
	{
		LastChar = get_char(ctx);
		int tab_size = 0;
		while (LastChar == '\t')
		{
			tab_size++;
			LastChar = get_char(ctx);
		}

		// 记录tab的数量
		ctx->tab_size = tab_size;
		// printf("%d\n", tab_size);
		// 缩进即使是0也要记录
		ctx->line_num = ctx->line_num + 1;

		return tok_tab;	
	}

	if (isalpha(LastChar))
	{
		
		ctx->identifier_str = LastChar;

		// printf("%c\n", LastChar);

		LastChar = get_char(ctx);
		// 完整的一个语元
		while (isalnum(LastChar) || LastChar == '_'){
			ctx->identifier_str += LastChar;
			LastChar = get_char(ctx);
		}	

		if (ctx->identifier_str == "seq_def")
		{
			return tok_seq_def_type;
		}

		if (ctx->identifier_str == "seq_comm_assoca_def")
		{
			return tok_seq_comm_assoca_def_type;
		}

		// printf("%s\n", ctx->identifier_str.c_str());
		if (ctx->identifier_str == "input_central_paral")
		{
			return tok_input_central_paral_type;
		}

		if (ctx->identifier_str == "iter_central_paral")
		{
			return tok_iter_central_paral_type;
		}

		// 一些保留字，33个
		int i;
		for (i = 0; i < ctx->remain_str_arr.size(); i++)
		{
			// printf("%s\n", ctx->remain_str_arr[i].c_str());
			if (ctx->identifier_str == ctx->remain_str_arr[i])
			{
				return tok_python_remain;
			}
		}



		// 以字母为开头的表达式，应该是函数声明的类型，和变量以及函数的名称
		return tok_identifier;
	}

	// 处理占位符
	if (LastChar == '_')
	{
		LastChar = get_char(ctx);
		return tok_place_holder;
	}

	// 处理数字
	if (isdigit(LastChar))
	{
		std::string num_str;

		// 记录当前是int还是double
		bool is_int = 1;

		while (isdigit(LastChar) || LastChar == '.')
		{
			if (LastChar == '.')
			{
				if (is_int == 0)
				{
					printf("error in num\n");
					exit(-1);
				}
				else
				{
					is_int = 0;
				}
			}

			num_str += LastChar;
			LastChar = get_char(ctx);
		}

		// 这里完整获取了一数字，整理完之后输出
		if (is_int == 1)
		{
			ctx->long_num_val = atol(num_str.c_str());
			return tok_int;
		}
		else
		{
			ctx->double_num_val = atof(num_str.c_str());
			return tok_double;
		}
	}

	// 处理注释
	if (LastChar == '#')
	{
		// Comment until end of line.
		do
			LastChar = getchar();
		while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');

		if (LastChar != EOF)
		{
			return get_tok(ctx);
		}
	}

	// 如果上面都处理不到，那么就是碰到了运算符和文件末尾
	if (LastChar == EOF)
	{
		// 遍历完之后重置一下
		LastChar = ' ';
		return tok_eof;
	}

	// 向下走一位
	int this_char = LastChar;
	LastChar = get_char(ctx);
	
	return this_char;
}

